
#ifndef _LIST_H_
#define _LIST_H_

#include "cell.h"

/**
 * Représente une liste simplement chainée
 */
struct s_List {
    Cell* first;
    Cell* last;
    int count;
} typedef List;

/**
 * Initialise une liste vide
 */
void list_initialize(List* list);

/**
 * Initialise une copie de la liste source dans la liste passée en argument 
 */
void list_initializeCopy(List* list, const List* source);

/**
 * Désaloue l'ensemble des ressources de la liste passée en argument
 */
void list_destroy(List** list);

/**
 * Copie en mémoire la liste src dans la list dest passé en argument
 */
void list_copy(List* list, const List* source);

/**
 * Supprimme l'ensemble des cellule contenues dans la liste passée en argument
 */
void list_clear(List* list);

/**
 * Obtient le nombre de cellules contenue dans la liste passée en argument
 */
int list_getCount(const List* list);

/**
 * Obtient l'adresse de la première cellule de la liste passée en argument
 */
Cell* list_getFirst(const List* list);

/**
 * Obtient la valeur de la première cellule de la liste passée en argument
 */
void* list_getFirstValue(const List* list);

/**
 * Obtient l'adresse de la dernière cellule de la liste passée en argument
 */
Cell* list_getLast(const List* list);

/**
 * Obtient la valeur de la dernière cellule de la liste passée en argument
 */
void* list_getLastValue(const List* list);

/**
 * Obtient l'adresse de la cellule dans la liste à l'index passé en argument  
 * @param list L'adresse de la liste
 * @return L'adresse de la cellule à l'index passée en argument ou NULL si non trouvé
 */
Cell* list_getAt(const List* list, int index);

/**
 * Obtient la valeur de la cellule dans la liste à l'index passé en argument
 * @param list L'adresse de la liste
 * @return L'adresse de la cellule à l'index passée en argument ou NULL si non trouvé
 */
void* list_getValueAt(const List* list, int index);

/**
 * Supprime la cellule dans la liuste à l'index passé en argument
 * @param list L'adresse de la liste
 * @return 0 si l'index ne fait pas parti de la liste, 1 sinon
 */
int list_removeAt(List* list, int index);

/**
 * Obtient l'adresse de la prémière cellule de la liste dont l'élément est égale à celui passé en argument
 * @param list L'adresse de la liste
 * @param cell Resultat : l'adresse de la cellule trouvée, ou NULL si aucun élément correspondant n'a été trouvé
 * @return l'index de la cellule trouvée, ou -1 si aucun élément correspondant n'a été trouvé
 */
int list_get(const List* list, void* value, Cell** cell);

/**
 * Obtient l'adresse de la prémière cellule de la liste dont l'élément est égale à celui passé en argument
 * @param list L'adresse de la liste
 * @param cell Resultat : l'adresse de la cellule trouvée, ou NULL si aucun élément correspondant n'a été trouvé
 * @return l'index de la cellule trouvée, ou -1 si aucun élément correspondant n'a été trouvé
 */
int list_getFirstOf(const List* list, void* value, int (*pIsEqual)(void*,void*), Cell** cell);

/**
 * Supprime la cellule de la liste dont l'élément est égale à celui passé en argument
 * @return 1 si la cellule a été supprimée, 0 si aucun élément correspondant n'a été trouvé
 */
int list_remove(List* list, void* value);

/**
 * Supprime la cellule de la liste dont l'élément est égale à celui passé en argument
 * @return 1 si la cellule a été supprimée, 0 si aucun élément correspondant n'a été trouvé
 */
int list_removeFirstOf(List* list, void* value, int (*pIsEqual)(void*,void*));


/**
 * Insère l'élément dans la liste à l'index passée en argument
 * @return 
 */
void list_insertAt(List* list, void* value, int index);

/**
  * Insère l'élément en première position de la liste passée en argument
  */
void list_insertFirst(List* list, void* value);

/**
 * Insère l'élément en dernière position de la liste passée en argument
 */
void list_insertLast(List* list, void* value);

#endif
